package com.jdk.learn.jvm;

/**
 * 关于内存分配问题的测试
 */
public class _006GCMemoryEdenRegion {
    /**
     * 配置gc日志  一切都是默认的情况下的测试
     * -verbose:gc -XX:+PrintGCDetails
     * @param args
     */
    public static void main01(String[] args) {
        byte[] b4=new byte[4*_10m];//分配4mb内存

        /**
         * 默认开启GC日志打印
         * 打印结果：
         *

         Heap
         PSYoungGen      total 35840K, used 7783K [0x00000000d8380000, 0x00000000dab80000, 0x0000000100000000)
         eden space 30720K, 25% used [0x00000000d8380000,0x00000000d8b19cb0,0x00000000da180000)
         from space 5120K, 0% used [0x00000000da680000,0x00000000da680000,0x00000000dab80000)
         to   space 5120K, 0% used [0x00000000da180000,0x00000000da180000,0x00000000da680000)
         ParOldGen       total 81920K, used 0K [0x0000000088a00000, 0x000000008da00000, 0x00000000d8380000)
         object space 81920K, 0% used [0x0000000088a00000,0x0000000088a00000,0x000000008da00000)
         Metaspace       used 2856K, capacity 4486K, committed 4864K, reserved 1056768K
         class space    used 301K, capacity 386K, committed 512K, reserved 1048576K


         解释：PSYoungGen Parallel Scavenge垃圾收集器处理新生代  共35840K(eden+survivor(一个),浪费一个Survivor区域)，使用 7783K 后边是内存偏移值
            Eden空间供30720K 使用25%
            from 5120  使用0%
            to 5120  使用0%
           ParOldGen(老年代，使用Par收集器)  共81920k 使用0
            对象空间 共81920k 使用0
         Metaspace 元空间 使用2856k  容量 4486 commited(已分配的) 4864 reserved(预留)1056768K
            Class空间 使用301k 容量 386k  已分配 512k  预留1048576K

        默认情况下，新老占比是1:2  新生代可用是90%

         */

    }

    /**
     * 配置基础vm参数
     *
     -Xmn10M -Xmx20M -Xms20M -XX:SurvivorRatio=8
     也就是堆内存20m 新生代10  老年代10m eden占80% 8m

     -XX:+PrintCommandLineFlags 打印相关配置参数
     -XX:+PrintNMTStatistics
     -XX:+UnlockDiagnosticVMOptions


     -verbose:gc
     -XX:+PrintGCDetails
     -Xmn10M
     -Xmx20M
     -Xms20M
     -XX:SurvivorRatio=8
     -XX:+PrintCommandLineFlags
     -XX:NativeMemoryTracking=summary
     -XX:+UnlockDiagnosticVMOptions
     -XX:+PrintNMTStatistics

     关于S区大小，官方公式：S=Y/(R+2)
        Y= 新生代容量
        R=SurvivorRatio设置的值
        假定Y=100，R=8，则S=100/10=10
     参阅官文:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html
     * @param args
     */
    private static final  int _10m=10*1024*1024;

    /**
     * -verbose:gc
     -XX:+PrintGCDetails
     -Xmn100M
     -Xmx200M
     -Xms200M
     -XX:SurvivorRatio=8
     -XX:+PrintCommandLineFlags
     -XX:+HeapDumpOnOutOfMemoryError
     -XX:+PrintGCTimeStamps
     -XX:+PrintTenuringDistribution
     * @param args
     */
    public static void main(String[] args) throws InterruptedException {
        byte[] b1=new byte[2*_10m];//分配20mb内存
        byte[] b2=new byte[2*_10m];//分配20mb内存
//        byte[] b_2=new byte[2*_10m];//分配20mb内存
        byte[] b3=new byte[2*_10m];//分配20mb内存
//        byte[] b5=new byte[2*_10m];//分配20mb内存
        byte[] b4=new byte[3*_10m];//分配30mb内存
//        byte[] b_6=new byte[4*_10m];//分配40mb内存

        Thread.sleep(Integer.MAX_VALUE);
        /**

         byte[] b1=new byte[2*_10m];//分配20mb内存
         byte[] b2=new byte[2*_10m];//分配20mb内存
         byte[] b3=new byte[2*_10m];//分配20mb内存
         byte[] b_6=new byte[4*_10m];//分配40mb内存


         Heap
         PSYoungGen      total 92160K, used 71279K [0x00000000f9c00000, 0x0000000100000000, 0x0000000100000000)
         eden space 81920K, 87% used [0x00000000f9c00000,0x00000000fe19bcd8,0x00000000fec00000)
         from space 10240K, 0% used [0x00000000ff600000,0x00000000ff600000,0x0000000100000000)
         to   space 10240K, 0% used [0x00000000fec00000,0x00000000fec00000,0x00000000ff600000)
         ParOldGen       total 102400K, used 40960K [0x00000000f3800000, 0x00000000f9c00000, 0x00000000f9c00000)
         object space 102400K, 40% used [0x00000000f3800000,0x00000000f6000010,0x00000000f9c00000)
         Metaspace       used 3247K, capacity 4568K, committed 4864K, reserved 1056768K
         class space    used 348K, capacity 392K, committed 512K, reserved 1048576K
         ----------分析
        参阅006.md解析
         -----------
            第四次分配，检测到对象大于eden区的一半，直接晋升老年代。


-------------------------------------------------------------------------------------------------------------------------------------------

         byte[] b_6=new byte[3*_10m];//分配30mb内存
--------------------------
         -XX:+HeapDumpOnOutOfMemoryError -XX:InitialHeapSize=209715200 -XX:MaxHeapSize=209715200 -XX:MaxNewSize=104857600 -XX:NewSize=104857600 -XX:+PrintCommandLineFlags -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:SurvivorRatio=8 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
         Connected to the target VM, address: '127.0.0.1:62499', transport: 'socket'
         0.337: [GC (Allocation Failure) [PSYoungGen: 69640K->1201K(92160K)] 69640K->62649K(194560K), 0.0321190 secs] [Times: user=0.11 sys=0.01, real=0.03 secs]
         0.369: [Full GC (Ergonomics) [PSYoungGen: 1201K->0K(92160K)] [ParOldGen: 61448K->62546K(102400K)] 62649K->62546K(194560K), [Metaspace: 3240K->3240K(1056768K)], 0.0146014 secs] [Times: user=0.06 sys=0.00, real=0.01 secs]
         Disconnected from the target VM, address: '127.0.0.1:62499', transport: 'socket'
         Heap
         PSYoungGen      total 92160K, used 33178K [0x00000000f9c00000, 0x0000000100000000, 0x0000000100000000)
         eden space 81920K, 40% used [0x00000000f9c00000,0x00000000fbc66800,0x00000000fec00000)
         from space 10240K, 0% used [0x00000000fec00000,0x00000000fec00000,0x00000000ff600000)
         to   space 10240K, 0% used [0x00000000ff600000,0x00000000ff600000,0x0000000100000000)
         ParOldGen       total 102400K, used 62546K [0x00000000f3800000, 0x00000000f9c00000, 0x00000000f9c00000)
         object space 102400K, 61% used [0x00000000f3800000,0x00000000f7514870,0x00000000f9c00000)
         Metaspace       used 3248K, capacity 4568K, committed 4864K, reserved 1056768K
         class space    used 348K, capacity 392K, committed 512K, reserved 1048576K

         -------
         三次分配后，空间使用接近70M，后来的对象为30m，无法在Eden区直接分配，对象不占用eden一半空间，无法直接在老年代分配。
         触发一次年轻代GC，将年轻代的对象晋升为老年代，接着ps会对old gen的剩余容量检测是否满足历次晋升条件，不满足则触发一次full gc。

-------------------------------------------------------------------------------------------------------------------
         注意：默认启动实例时会加载ext包中的许多依赖，将近四百多  可通过 -verbose:class 进行查看
         (
         D:\work\jvm\demo>java -verbose:class -XX:+PrintGCDetails -Xmn10M -Xmx20M -Xms20M -XX:SurvivorRatio=8 -XX:+HeapDumpBeforeFullGC Gc >d:\detail.txt

         D:\work\jvm\demo>java -verbose:gc -XX:+PrintGCDetails -Xmn10M -Xmx20M -Xms20M -XX:SurvivorRatio=8 -XX:+HeapDumpBeforeFullGC Gc
         )
         verbose：gc的话，可以通过mat进行分析引用。

         */
    }
}
